"use strict";
const path = require("path");
const { isObject } = require("@zhuj-cli-dev/utils");
const pkgDir = require("pkg-dir").sync;
const formatPath = require("@zhuj-cli-dev/format-path");
const pathExists = require("path-exists").sync;
const fse = require("fs-extra");
const npminstall = require("npminstall");
const {
  getDefaultRegistry,
  getNpmLatestVersion,
} = require("@zhuj-cli-dev/get-npm-info");

class Package {
  constructor(options) {
    console.log("Package constructor");
    if (!options) {
      throw new Error("Package 类的参数 options 不能为空");
    }

    if (!isObject(options)) {
      throw new Error("参数 options 必须是对象");
    }

    // package 的目标路径
    this.targetPath = options.targetPath;
    // package 存储路径
    this.storeDir = options.storeDir;
    // package 的名字
    this.packageName = options.packageName;
    // package 的版本
    this.packageVersion = options.packageVersion;
    // 缓存文件前缀
    this.chacheFilePathPrefix = this.packageName.replaceAll("/", "_");
  }

  // 缓存文件逻辑获取
  // _@zhuj-cli-dev_utils@1.0.5@@zhuj-cli-dev // 缓存的文件
  // @zhuj-cli-dev/utils 1.0.5 需要转换为第一个
  get chacheFilePath() {
    return path.resolve(
      this.storeDir,
      `_${this.chacheFilePathPrefix}@${this.packageVersion}@${this.packageName}`
    );
  }

  // 获取指定版本的缓存文件路径
  getSpacificCacheFilePath(packageVersion) {
    return path.resolve(
      this.storeDir,
      `_${this.chacheFilePathPrefix}@${packageVersion}@${this.packageName}`
    );
  }

  // 判断当前package是否存在
  async exists() {
    console.log("Package exist");
    if (this.storeDir) {
      await this.prepare();
      // 缓存文件的路径
      return pathExists(this.chacheFilePath);
    } else {
      return pathExists(this.targetPath);
    }
  }

  async prepare() {
    if (this.storeDir && !pathExists(this.storeDir)) {
      fse.mkdirpSync(this.storeDir);
    }
    if (this.packageVersion === "latest") {
      this.packageVersion = await getNpmLatestVersion(this.packageName);
    }
  }

  // 安装package
  async install() {
    console.log("Package install");
    await this.prepare();
    await npminstall({
      root: this.targetPath,
      storeDir: this.storePath,
      registrt: getDefaultRegistry(),
      pkgs: [{ name: this.packageName, version: this.packageVersion }],
    });
  }

  // 更新package
  async update() {
    console.log("Package update");
    await this.prepare();
    // 1、获取最新版本号
    const latestVersion = await getNpmLatestVersion(this.packageName);
    // 2、获取最新版本号对应的路径
    const latestFilePath = this.getSpacificCacheFilePath(latestVersion);
    // 3、如果不存在，则直接安装最新版本
    if (!pathExists(latestFilePath)) {
      await npminstall({
        root: this.targetPath,
        storeDir: this.storePath,
        registrt: getDefaultRegistry(),
        pkgs: [{ name: this.packageName, version: latestVersion }],
      });
      this.packageVersion = latestVersion;
    } else {
      this.packageVersion = latestVersion;
    }
  }

  // 获取入口文件的路径
  getRootFilePath() {
    function _getRootFile(targetPath) {
      // 1、获取 package.json 所在目录- pkg-dir
      const dir = pkgDir(targetPath);
      if (dir) {
        // 2、读取 package.json require()
        const pkgFile = require(path.resolve(dir, "package.json"));

        // 3、main/lib - path
        if (pkgFile && pkgFile.main) {
          // 4、路径兼容（macOS/windows）
          const p = path.resolve(dir, pkgFile.main);
          return formatPath(p);
        }
      }
      return null;
    }

    if (this.storeDir) {
      return _getRootFile(this.chacheFilePath);
    } else {
      return _getRootFile(this.targetPath);
    }
  }
}

module.exports = Package;
